<template><div><h2 id="社会化登录" tabindex="-1"><a class="header-anchor" href="#社会化登录"><span>社会化登录</span></a></h2>
<p>Yii2 官方扩展 <code v-pre>yii2-authclient</code>，为 Yii 框架 2.0 增加了 <a href="http://openid.net/" target="_blank" rel="noopener noreferrer">OpenID</a>、<a href="http://oauth.net/1/" target="_blank" rel="noopener noreferrer">OAuth</a>、<a href="http://oauth.net/2/" target="_blank" rel="noopener noreferrer">OAuth2</a> 和 <a href="http://openid.net/connect/" target="_blank" rel="noopener noreferrer">OpenId Connect</a> 消费者。</p>
<h2 id="安装" tabindex="-1"><a class="header-anchor" href="#安装"><span>安装</span></a></h2>
<p>安装此扩展的首选方式是通过 <a href="http://getcomposer.org/download/" target="_blank" rel="noopener noreferrer">composer</a>，命令如下：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line"><span class="token function">composer</span> require yiisoft/yii2-authclient</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>或者在 <code v-pre>composer.json</code> 文件中的 require 部分增加以下内容：</p>
<div class="language-json line-numbers-mode" data-highlighter="prismjs" data-ext="json" data-title="json"><pre v-pre class="language-json"><code><span class="line"><span class="token property">"yiisoft/yii2-authclient"</span><span class="token operator">:</span> <span class="token string">"~2.2.0"</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>然后执行 <code v-pre>composer install</code> 命令即可。</p>
<h2 id="配置应用" tabindex="-1"><a class="header-anchor" href="#配置应用"><span>配置应用</span></a></h2>
<p>扩展安装后，你需要设置认证客户端的收集应用程序组件：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'components'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'authClientCollection'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'yii\authclient\Collection'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'clients'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token string single-quoted-string">'google'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                    <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'yii\authclient\clients\Google'</span><span class="token punctuation">,</span></span>
<span class="line">                    <span class="token string single-quoted-string">'clientId'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'google_client_id'</span><span class="token punctuation">,</span></span>
<span class="line">                    <span class="token string single-quoted-string">'clientSecret'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'google_client_secret'</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'facebook'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                    <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'yii\authclient\clients\Facebook'</span><span class="token punctuation">,</span></span>
<span class="line">                    <span class="token string single-quoted-string">'clientId'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'facebook_client_id'</span><span class="token punctuation">,</span></span>
<span class="line">                    <span class="token string single-quoted-string">'clientSecret'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'facebook_client_secret'</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token comment">// etc.</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span></span>
<span class="line">        <span class="token comment">// ...</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Yii2 提供了以下开箱即用的客户端：</p>
<ul>
<li><code v-pre>yii\authclient\clients\Facebook</code>：Facebook</li>
<li><code v-pre>yii\authclient\clients\GitHub</code>：GitHub</li>
<li><code v-pre>yii\authclient\clients\Google</code>：Google OAuth</li>
<li><code v-pre>yii\authclient\clients\GoogleHybrid</code>：Google OAuth Hybrid</li>
<li><code v-pre>yii\authclient\clients\LinkedIn</code>：LinkedIn</li>
<li><code v-pre>yii\authclient\clients\Live</code>：Microsoft Live</li>
<li><code v-pre>yii\authclient\clients\Twitter</code>：Twitter</li>
<li><code v-pre>yii\authclient\clients\VKontakte</code>：VKontakte</li>
<li><code v-pre>yii\authclient\clients\Yandex</code>：Yandex</li>
</ul>
<p>每个客户机的配置略有不同。对于 OAuth，它需要从你将要使用的服务中获取客户端 ID 和密钥。而对于 OpenID，它在大多数情况下都是开箱即用的。</p>
<h2 id="存储授权数据" tabindex="-1"><a class="header-anchor" href="#存储授权数据"><span>存储授权数据</span></a></h2>
<p>In order to recognize the user authenticated via external service we need to store ID provided on first authentication and then check against it on subsequent authentications. It’s not a good idea to limit login options to external services only since these may fail and there won’t be a way for the user to log in. Instead, it’s better to provide both external authentication and good old login and password.</p>
<p>If we’re storing user information in a database the corresponding migration code could be the following:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">m</span><span class="token operator">??</span><span class="token operator">??</span><span class="token operator">??</span><span class="token constant">_</span><span class="token operator">??</span><span class="token operator">??</span><span class="token operator">??</span>_auth <span class="token keyword">extends</span> <span class="token class-name class-name-fully-qualified"><span class="token punctuation">\</span>yii<span class="token punctuation">\</span>db<span class="token punctuation">\</span>Migration</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">up</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">createTable</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'user'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">primaryKey</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'username'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token keyword type-declaration">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">notNull</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'auth_key'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token keyword type-declaration">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">notNull</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'password_hash'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token keyword type-declaration">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">notNull</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'password_reset_token'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token keyword type-declaration">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">notNull</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'email'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token keyword type-declaration">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">notNull</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'github'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token keyword type-declaration">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'status'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">smallInteger</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">notNull</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">defaultValue</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'created_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">integer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">notNull</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'updated_at'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">integer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">notNull</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">createTable</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'auth'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">primaryKey</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'user_id'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">integer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">notNull</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'source'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token keyword type-declaration">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">notNull</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'source_id'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token keyword type-declaration">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">notNull</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">addForeignKey</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'fk-auth-user_id-user-id'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'auth'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'user_id'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'user'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'id'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'CASCADE'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'CASCADE'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">down</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">dropTable</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'auth'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">dropTable</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'user'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>In the above example <code v-pre>user</code> is a standard table that is used in advanced project template to store user info. Each user can authenticate using multiple external services therefore each <code v-pre>user</code> record can relate to multiple <code v-pre>auth</code> records. In the <code v-pre>auth</code> table <code v-pre>source</code> is the name of the auth provider used and <code v-pre>source_id</code> is unique user identifier that is provided by external service after successful login.</p>
<p>Using tables created above we can generate <code v-pre>Auth</code> model. No further adjustments needed.</p>
<h2 id="向控制器添加动作" tabindex="-1"><a class="header-anchor" href="#向控制器添加动作"><span>向控制器添加动作</span></a></h2>
<p>Next step is to add [[yii\authclient\AuthAction]] to a web controller and provide a <code v-pre>successCallback</code> implementation, which is suitable for your needs. Typically, final controller code may look like following:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">app<span class="token punctuation">\</span>components<span class="token punctuation">\</span>AuthHandler</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">SiteController</span> <span class="token keyword">extends</span> <span class="token class-name">Controller</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">actions</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'auth'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'yii\authclient\AuthAction'</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'successCallback'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token variable">$this</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'onAuthSuccess'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">onAuthSuccess</span><span class="token punctuation">(</span><span class="token variable">$client</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">AuthHandler</span><span class="token punctuation">(</span><span class="token variable">$client</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">handle</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Note that it’s important for <code v-pre>auth</code> action to be public accessible, so make sure it’s not denied by access control filter.</p>
<p>Where AuthHandler implementation could be like this:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">app<span class="token punctuation">\</span>components</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">app<span class="token punctuation">\</span>models<span class="token punctuation">\</span>Auth</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">app<span class="token punctuation">\</span>models<span class="token punctuation">\</span>User</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Yii</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>authclient<span class="token punctuation">\</span>ClientInterface</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>helpers<span class="token punctuation">\</span>ArrayHelper</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * AuthHandler handles successful authentication via Yii auth component</span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">AuthHandler</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * <span class="token keyword">@var</span> <span class="token class-name">ClientInterface</span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">private</span> <span class="token variable">$client</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">__construct</span><span class="token punctuation">(</span><span class="token class-name type-declaration">ClientInterface</span> <span class="token variable">$client</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">client</span> <span class="token operator">=</span> <span class="token variable">$client</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">handle</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$attributes</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">client</span><span class="token operator">-></span><span class="token function">getUserAttributes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token variable">$email</span> <span class="token operator">=</span> <span class="token class-name static-context">ArrayHelper</span><span class="token operator">::</span><span class="token function">getValue</span><span class="token punctuation">(</span><span class="token variable">$attributes</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'email'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token variable">$id</span> <span class="token operator">=</span> <span class="token class-name static-context">ArrayHelper</span><span class="token operator">::</span><span class="token function">getValue</span><span class="token punctuation">(</span><span class="token variable">$attributes</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'id'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token variable">$nickname</span> <span class="token operator">=</span> <span class="token class-name static-context">ArrayHelper</span><span class="token operator">::</span><span class="token function">getValue</span><span class="token punctuation">(</span><span class="token variable">$attributes</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'login'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token comment">/* @var Auth $auth */</span></span>
<span class="line">        <span class="token variable">$auth</span> <span class="token operator">=</span> <span class="token class-name static-context">Auth</span><span class="token operator">::</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">where</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'source'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">client</span><span class="token operator">-></span><span class="token function">getId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'source_id'</span> <span class="token operator">=></span> <span class="token variable">$id</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">one</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">user</span><span class="token operator">-></span><span class="token property">isGuest</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$auth</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// login</span></span>
<span class="line">                <span class="token comment">/* @var User $user */</span></span>
<span class="line">                <span class="token variable">$user</span> <span class="token operator">=</span> <span class="token variable">$auth</span><span class="token operator">-></span><span class="token property">user</span><span class="token punctuation">;</span></span>
<span class="line">                <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">updateUserInfo</span><span class="token punctuation">(</span><span class="token variable">$user</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">                <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">user</span><span class="token operator">-></span><span class="token function">login</span><span class="token punctuation">(</span><span class="token variable">$user</span><span class="token punctuation">,</span> <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">params</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'user.rememberMeDuration'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">            <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// signup</span></span>
<span class="line">                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$email</span> <span class="token operator">!==</span> <span class="token constant">null</span> <span class="token operator">&amp;&amp;</span> <span class="token class-name static-context">User</span><span class="token operator">::</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">where</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'email'</span> <span class="token operator">=></span> <span class="token variable">$email</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">exists</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">                    <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token function">getSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">setFlash</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'error'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">                        <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token function">t</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'app'</span><span class="token punctuation">,</span> <span class="token string double-quoted-string">"User with the same email as in {client} account already exists but isn't linked to it. Login using email first to link it."</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'client'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">client</span><span class="token operator">-></span><span class="token function">getTitle</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">                    <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">                <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span></span>
<span class="line">                    <span class="token variable">$password</span> <span class="token operator">=</span> <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">security</span><span class="token operator">-></span><span class="token function">generateRandomString</span><span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">                    <span class="token variable">$user</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">                        <span class="token string single-quoted-string">'username'</span> <span class="token operator">=></span> <span class="token variable">$nickname</span><span class="token punctuation">,</span></span>
<span class="line">                        <span class="token string single-quoted-string">'github'</span> <span class="token operator">=></span> <span class="token variable">$nickname</span><span class="token punctuation">,</span></span>
<span class="line">                        <span class="token string single-quoted-string">'email'</span> <span class="token operator">=></span> <span class="token variable">$email</span><span class="token punctuation">,</span></span>
<span class="line">                        <span class="token string single-quoted-string">'password'</span> <span class="token operator">=></span> <span class="token variable">$password</span><span class="token punctuation">,</span></span>
<span class="line">                        <span class="token comment">// 'status</span><span class="token string single-quoted-string">' => User::STATUS_ACTIVE // make sure you set status properly</span>
<span class="line">                    ]);</span>
<span class="line">                    $user->generateAuthKey();</span>
<span class="line">                    $user->generatePasswordResetToken();</span>
<span class="line"></span>
<span class="line">                    $transaction = User::getDb()->beginTransaction();</span>
<span class="line"></span>
<span class="line">                    if ($user->save()) {</span>
<span class="line">                        $auth = new Auth([</span>
<span class="line">                            '</span>user_id<span class="token string single-quoted-string">' => $user->id,</span>
<span class="line">                            '</span>source<span class="token string single-quoted-string">' => $this->client->getId(),</span>
<span class="line">                            '</span>source_id<span class="token string single-quoted-string">' => (string)$id,</span>
<span class="line">                        ]);</span>
<span class="line">                        if ($auth->save()) {</span>
<span class="line">                            $transaction->commit();</span>
<span class="line">                            Yii::$app->user->login($user, Yii::$app->params['</span>user<span class="token operator">.</span>rememberMeDuration<span class="token string single-quoted-string">']);</span>
<span class="line">                        } else {</span>
<span class="line">                            Yii::$app->getSession()->setFlash('</span>error<span class="token string single-quoted-string">', [</span>
<span class="line">                                Yii::t('</span>app<span class="token string single-quoted-string">', '</span>Unable to save <span class="token punctuation">{</span>client<span class="token punctuation">}</span> account<span class="token punctuation">:</span> <span class="token punctuation">{</span>errors<span class="token punctuation">}</span><span class="token string single-quoted-string">', [</span>
<span class="line">                                    '</span>client<span class="token string single-quoted-string">' => $this->client->getTitle(),</span>
<span class="line">                                    '</span>errors<span class="token string single-quoted-string">' => json_encode($auth->getErrors()),</span>
<span class="line">                                ]),</span>
<span class="line">                            ]);</span>
<span class="line">                        }</span>
<span class="line">                    } else {</span>
<span class="line">                        Yii::$app->getSession()->setFlash('</span>error<span class="token string single-quoted-string">', [</span>
<span class="line">                            Yii::t('</span>app<span class="token string single-quoted-string">', '</span>Unable to save user<span class="token punctuation">:</span> <span class="token punctuation">{</span>errors<span class="token punctuation">}</span><span class="token string single-quoted-string">', [</span>
<span class="line">                                '</span>client<span class="token string single-quoted-string">' => $this->client->getTitle(),</span>
<span class="line">                                '</span>errors<span class="token string single-quoted-string">' => json_encode($user->getErrors()),</span>
<span class="line">                            ]),</span>
<span class="line">                        ]);</span>
<span class="line">                    }</span>
<span class="line">                }</span>
<span class="line">            }</span>
<span class="line">        } else { // user already logged in</span>
<span class="line">            if (!$auth) { // add auth provider</span>
<span class="line">                $auth = new Auth([</span>
<span class="line">                    '</span>user_id<span class="token string single-quoted-string">' => Yii::$app->user->id,</span>
<span class="line">                    '</span>source<span class="token string single-quoted-string">' => $this->client->getId(),</span>
<span class="line">                    '</span>source_id<span class="token string single-quoted-string">' => (string)$attributes['</span>id<span class="token string single-quoted-string">'],</span>
<span class="line">                ]);</span>
<span class="line">                if ($auth->save()) {</span>
<span class="line">                    /** @var User $user */</span>
<span class="line">                    $user = $auth->user;</span>
<span class="line">                    $this->updateUserInfo($user);</span>
<span class="line">                    Yii::$app->getSession()->setFlash('</span>success<span class="token string single-quoted-string">', [</span>
<span class="line">                        Yii::t('</span>app<span class="token string single-quoted-string">', '</span>Linked <span class="token punctuation">{</span>client<span class="token punctuation">}</span> account<span class="token operator">.</span><span class="token string single-quoted-string">', [</span>
<span class="line">                            '</span>client<span class="token string single-quoted-string">' => $this->client->getTitle()</span>
<span class="line">                        ]),</span>
<span class="line">                    ]);</span>
<span class="line">                } else {</span>
<span class="line">                    Yii::$app->getSession()->setFlash('</span>error<span class="token string single-quoted-string">', [</span>
<span class="line">                        Yii::t('</span>app<span class="token string single-quoted-string">', '</span>Unable to link <span class="token punctuation">{</span>client<span class="token punctuation">}</span> account<span class="token punctuation">:</span> <span class="token punctuation">{</span>errors<span class="token punctuation">}</span><span class="token string single-quoted-string">', [</span>
<span class="line">                            '</span>client<span class="token string single-quoted-string">' => $this->client->getTitle(),</span>
<span class="line">                            '</span>errors<span class="token string single-quoted-string">' => json_encode($auth->getErrors()),</span>
<span class="line">                        ]),</span>
<span class="line">                    ]);</span>
<span class="line">                }</span>
<span class="line">            } else { // there'</span>s existing auth</span>
<span class="line">                <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token function">getSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">setFlash</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'error'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">                    <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token function">t</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'app'</span><span class="token punctuation">,</span></span>
<span class="line">                        <span class="token string single-quoted-string">'Unable to link {client} account. There is another user using it.'</span><span class="token punctuation">,</span></span>
<span class="line">                        <span class="token punctuation">[</span><span class="token string single-quoted-string">'client'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">client</span><span class="token operator">-></span><span class="token function">getTitle</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">            <span class="token punctuation">}</span></span>
<span class="line">        <span class="token punctuation">}</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * <span class="token keyword">@param</span> <span class="token class-name">User</span> <span class="token parameter">$user</span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">private</span> <span class="token keyword">function</span> <span class="token function-definition function">updateUserInfo</span><span class="token punctuation">(</span><span class="token class-name type-declaration">User</span> <span class="token variable">$user</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$attributes</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">client</span><span class="token operator">-></span><span class="token function">getUserAttributes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token variable">$github</span> <span class="token operator">=</span> <span class="token class-name static-context">ArrayHelper</span><span class="token operator">::</span><span class="token function">getValue</span><span class="token punctuation">(</span><span class="token variable">$attributes</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'login'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$user</span><span class="token operator">-></span><span class="token property">github</span> <span class="token operator">===</span> <span class="token constant">null</span> <span class="token operator">&amp;&amp;</span> <span class="token variable">$github</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">            <span class="token variable">$user</span><span class="token operator">-></span><span class="token property">github</span> <span class="token operator">=</span> <span class="token variable">$github</span><span class="token punctuation">;</span></span>
<span class="line">            <span class="token variable">$user</span><span class="token operator">-></span><span class="token function">save</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token punctuation">}</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><code v-pre>successCallback</code> method is called when user was successfully authenticated via external service. Via <code v-pre>$client</code> instance we can retrieve information received. In our case we’d like to:</p>
<ul>
<li>If user is guest and record found in auth then log this user in.</li>
<li>If user is guest and record not found in auth then create new user and make a record in auth table. Then log in.</li>
<li>If user is logged in and record not found in auth then try connecting additional account (save its data into auth table).</li>
</ul>
<blockquote>
<p>Note: different Auth clients may require different approaches while handling authentication success. For example: Twitter does not allow returning of the user email, so you have to deal with this somehow.</p>
</blockquote>
<h3 id="认证客户端基本结构" tabindex="-1"><a class="header-anchor" href="#认证客户端基本结构"><span>认证客户端基本结构</span></a></h3>
<p>Although, all clients are different they share same basic interface [[yii\authclient\ClientInterface]], which governs common API.</p>
<p>Each client has some descriptive data, which can be used for different purposes:</p>
<ul>
<li><code v-pre>id</code> - unique client id, which separates it from other clients, it could be used in URLs, logs etc.</li>
<li><code v-pre>name</code> - external auth provider name, which this client is match too. Different auth clients can share the same name, if they refer to the same external auth provider. For example: clients for Google and Google Hybrid have same named “google”. This attribute can be used inside the database, CSS styles and so on.</li>
<li><code v-pre>title</code> - user-friendly name for the external auth provider, it is used to present auth client at the view layer.</li>
</ul>
<p>Each auth client has different auth flow, but all of them supports <code v-pre>getUserAttributes()</code> method, which can be invoked if authentication was successful.</p>
<p>This method allows you to get information about external user account, such as ID, email address, full name, preferred language etc. Note that for each provider fields available may vary in both existence and names.</p>
<p>Defining list of attributes, which external auth provider should return, depends on client type:</p>
<ul>
<li>[[yii\authclient\OpenId]]: combination of <code v-pre>requiredAttributes</code> and <code v-pre>optionalAttributes</code>.</li>
<li>[[yii\authclient\OAuth1]] and [[yii\authclient\OAuth2]]: field <code v-pre>scope</code>, note that different providers use different formats for the scope.</li>
</ul>
<blockquote>
<p>Tip: If you are using several clients, you can unify the structure of the attributes, which they return, using [[yii\authclient\BaseClient::$normalizeUserAttributeMap]].</p>
</blockquote>
<h2 id="添加小部件到登录视图" tabindex="-1"><a class="header-anchor" href="#添加小部件到登录视图"><span>添加小部件到登录视图</span></a></h2>
<p>There’s ready to use [[yii\authclient\widgets\AuthChoice]] widget to use in views:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?=</span> <span class="token class-name class-name-fully-qualified static-context">yii<span class="token punctuation">\</span>authclient<span class="token punctuation">\</span>widgets<span class="token punctuation">\</span>AuthChoice</span><span class="token operator">::</span><span class="token function">widget</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">     <span class="token string single-quoted-string">'baseAuthUrl'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'site/auth'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">     <span class="token string single-quoted-string">'popupMode'</span> <span class="token operator">=></span> <span class="token constant boolean">false</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token delimiter important">?></span></span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="github-客户端的注意事项" tabindex="-1"><a class="header-anchor" href="#github-客户端的注意事项"><span>GitHub 客户端的注意事项</span></a></h2>
<p>Recently due to potential changes in GitHub callback handling, ensure that <code v-pre>authclient=github</code> is present in URL query param in Authorization Callback URL to avoid 404 error thrown when GitHub redirects user back to our app.</p>
<p>Example: Let’s say my app is at <code v-pre>https://example.com</code>. In order to implement “Login with GitHub” feature into my app, I will create a new Oauth app for my <code v-pre>example.com</code> at <a href="https://github.com/settings/applications/new" target="_blank" rel="noopener noreferrer">github.com/settings/applications/n...</a>. In input field “Authorization callback URL” if I put <code v-pre>https://example.com/site/auth</code>, then I will get 404 error thrown by <a href="https://github.com/yiisoft/yii2-authclient/blob/master/src/AuthAction.php#L213" target="_blank" rel="noopener noreferrer"><code v-pre>run()</code></a> method. In order to fix this issue, above query param is required. So putting the “Authorization callback URL” value to <code v-pre>https://example.com/site/auth?authclient=github</code> is required.</p>
<h2 id="通过额外-api-调用获得附加数据" tabindex="-1"><a class="header-anchor" href="#通过额外-api-调用获得附加数据"><span>通过额外 API 调用获得附加数据</span></a></h2>
<p>Both [[\yii\authclient\OAuth1]] and [[\yii\authclient\OAuth2]] provide method <code v-pre>api()</code>, which can be used to access external auth provider REST API.</p>
<p>To use API calls, you need to setup [[\yii\authclient\BaseOAuth::apiBaseUrl]] according to the API specification. Then you can call [[\yii\authclient\BaseOAuth::api()]] method:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>authclient<span class="token punctuation">\</span>OAuth2</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$client</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">OAuth2</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// ...</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$client</span><span class="token operator">-></span><span class="token property">apiBaseUrl</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'https://www.googleapis.com/oauth2/v1'</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token variable">$userInfo</span> <span class="token operator">=</span> <span class="token variable">$client</span><span class="token operator">-></span><span class="token function">api</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'userinfo'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'GET'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Method [[\yii\authclient\BaseOAuth::api()]] is very basic and does not provide enough flexibility required for some API commands. You may use [[\yii\authclient\BaseOAuth::createApiRequest()]] instead - it will create an instance of [[\yii\httpclient\Request]], which allows much more control over HTTP request composition. For example:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token comment">/* @var $client \yii\authclient\OAuth2 */</span></span>
<span class="line"><span class="token variable">$client</span> <span class="token operator">=</span> <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">authClientCollection</span><span class="token operator">-></span><span class="token function">getClient</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'someOAuth2'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// find user to add to external service:</span></span>
<span class="line"><span class="token variable">$user</span> <span class="token operator">=</span> <span class="token class-name static-context">User</span><span class="token operator">::</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">andWhere</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'email'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'johndoe@domain.com'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">one</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$response</span> <span class="token operator">=</span> <span class="token variable">$client</span><span class="token operator">-></span><span class="token function">createApiRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">-></span><span class="token function">setMethod</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'GET'</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">-></span><span class="token function">setUrl</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'users'</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">-></span><span class="token function">setData</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token property">id</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">-></span><span class="token function">send</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$response</span><span class="token operator">-></span><span class="token property">statusCode</span> <span class="token operator">!=</span> <span class="token number">404</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name class-name-fully-qualified"><span class="token punctuation">\</span>Exception</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'User "johndoe@domain.com" already exist'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$response</span> <span class="token operator">=</span> <span class="token variable">$client</span><span class="token operator">-></span><span class="token function">createApiRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">-></span><span class="token function">setMethod</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'PUT'</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">-></span><span class="token function">setUrl</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'users'</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">-></span><span class="token function">setData</span><span class="token punctuation">(</span><span class="token variable">$user</span><span class="token operator">-></span><span class="token property">attributes</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">-></span><span class="token function">addHeaders</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'MyHeader'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'my-value'</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">-></span><span class="token function">send</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token variable">$response</span><span class="token operator">-></span><span class="token property">isOk</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// failure</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"><span class="token keyword">echo</span> <span class="token variable">$response</span><span class="token operator">-></span><span class="token property">data</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'id'</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Please refer to <a href="https://github.com/yiisoft/yii2-httpclient" target="_blank" rel="noopener noreferrer">yii2-httpclient</a> documentation for details about HTTP request sending.</p>
<p>Request created via [[\yii\authclient\BaseOAuth::createApiRequest()]] will be automatically signed up (in case of OAuth 1.0 usage) and have access token applied before being sent. If you wish to gain full control over these processes, you should use [[\yii\authclient\BaseClient::createRequest()]] instead. You may use [[\yii\authclient\BaseOAuth::applyAccessTokenToRequest()]] and [[yii\authclient\OAuth1::signRequest()]] method to perform missing actions for the API request. For example:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token comment">/* @var $client \yii\authclient\OAuth1 */</span></span>
<span class="line"><span class="token variable">$client</span> <span class="token operator">=</span> <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">authClientCollection</span><span class="token operator">-></span><span class="token function">getClient</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'someOAuth1'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$request</span> <span class="token operator">=</span> <span class="token variable">$client</span><span class="token operator">-></span><span class="token function">createRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">-></span><span class="token function">setMethod</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'GET'</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">-></span><span class="token function">setUrl</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'users'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$client</span><span class="token operator">-></span><span class="token function">applyAccessTokenToRequest</span><span class="token punctuation">(</span><span class="token variable">$request</span><span class="token punctuation">,</span> <span class="token variable">$myAccessToken</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// use custom access token for API</span></span>
<span class="line"><span class="token variable">$client</span><span class="token operator">-></span><span class="token function">signRequest</span><span class="token punctuation">(</span><span class="token variable">$request</span><span class="token punctuation">,</span> <span class="token variable">$myAccessToken</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// sign request with custom access token</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$response</span> <span class="token operator">=</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token function">send</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="自定义认证客户端" tabindex="-1"><a class="header-anchor" href="#自定义认证客户端"><span>自定义认证客户端</span></a></h2>
<p>You may create your own auth client for any external auth provider, which supports OpenId or OAuth protocol. To do so, first of all, you need to find out which protocol is supported by the external auth provider, this will give you the name of the base class for your extension:</p>
<ul>
<li>For OAuth 2 use [[yii\authclient\OAuth2]].</li>
<li>For OAuth 1/1.0a use [[yii\authclient\OAuth1]].</li>
<li>For OpenID use [[yii\authclient\OpenId]].</li>
</ul>
<p>At this stage you can determine auth client default name, title and view options, declaring corresponding methods:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>authclient<span class="token punctuation">\</span>OAuth2</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">MyAuthClient</span> <span class="token keyword">extends</span> <span class="token class-name">OAuth2</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">protected</span> <span class="token keyword">function</span> <span class="token function-definition function">defaultName</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token string single-quoted-string">'my_auth_client'</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">protected</span> <span class="token keyword">function</span> <span class="token function-definition function">defaultTitle</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token string single-quoted-string">'My Auth Client'</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">protected</span> <span class="token keyword">function</span> <span class="token function-definition function">defaultViewOptions</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'popupWidth'</span> <span class="token operator">=></span> <span class="token number">800</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'popupHeight'</span> <span class="token operator">=></span> <span class="token number">500</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Depending on actual base class, you will need to redeclare different fields and methods.</p>
<h3 id="openid" tabindex="-1"><a class="header-anchor" href="#openid"><span>OpenId</span></a></h3>
<p>All you need is to specify auth URL, by redeclaring [[yii\authclient\OpenId::authUrl|authUrl]] field. You may also setup default required and/or optional attributes. For example:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>authclient<span class="token punctuation">\</span>OpenId</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">MyAuthClient</span> <span class="token keyword">extends</span> <span class="token class-name">OpenId</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token variable">$authUrl</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'https://www.my.com/openid/'</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">public</span> <span class="token variable">$requiredAttributes</span> <span class="token operator">=</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'contact/email'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">public</span> <span class="token variable">$optionalAttributes</span> <span class="token operator">=</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'namePerson/first'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'namePerson/last'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="oauth2" tabindex="-1"><a class="header-anchor" href="#oauth2"><span>OAuth2</span></a></h3>
<p>You will need to specify:</p>
<ul>
<li>Auth URL by redeclaring [[yii\authclient\OAuth2::authUrl|authUrl]] field.</li>
<li>Token request URL by redeclaring [[yii\authclient\OAuth2::tokenUrl|tokenUrl]] field.</li>
<li>API base URL by redeclaring [[yii\authclient\OAuth2::apiBaseUrl|apiBaseUrl]] field.</li>
<li>User attribute fetching strategy by redeclaring [[yii\authclient\OAuth2::initUserAttributes()|initUserAttributes()]] method.</li>
</ul>
<p>For example:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>authclient<span class="token punctuation">\</span>OAuth2</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">MyAuthClient</span> <span class="token keyword">extends</span> <span class="token class-name">OAuth2</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token variable">$authUrl</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'https://www.my.com/oauth2/auth'</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">public</span> <span class="token variable">$tokenUrl</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'https://www.my.com/oauth2/token'</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">public</span> <span class="token variable">$apiBaseUrl</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'https://www.my.com/apis/oauth2/v1'</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">protected</span> <span class="token keyword">function</span> <span class="token function-definition function">initUserAttributes</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">api</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'userinfo'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'GET'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>You may also specify default auth scopes.</p>
<blockquote>
<p>Note: Some OAuth providers may not follow OAuth standards clearly, introducing differences, and may require additional efforts to implement clients for.</p>
</blockquote>
<h3 id="oauth1" tabindex="-1"><a class="header-anchor" href="#oauth1"><span>OAuth1</span></a></h3>
<p>You will need to specify:</p>
<ul>
<li>Auth URL by redeclaring [[yii\authclient\OAuth1::authUrl|authUrl]] field.</li>
<li>Request token URL by redeclaring [[yii\authclient\OAuth1::requestTokenUrl|requestTokenUrl]] field.</li>
<li>Access token URL by redeclaring [[yii\authclient\OAuth1::accessTokenUrl|accessTokenUrl]] field.</li>
<li>API base URL by redeclaring [[yii\authclient\OAuth1::apiBaseUrl|apiBaseUrl]] field.</li>
<li>User attribute fetching strategy by redeclaring [[yii\authclient\OAuth1::initUserAttributes()|initUserAttributes()]] method.</li>
</ul>
<p>For example:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>authclient<span class="token punctuation">\</span>OAuth1</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">MyAuthClient</span> <span class="token keyword">extends</span> <span class="token class-name">OAuth1</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token variable">$authUrl</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'https://www.my.com/oauth/auth'</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">public</span> <span class="token variable">$requestTokenUrl</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'https://www.my.com/oauth/request_token'</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">public</span> <span class="token variable">$accessTokenUrl</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'https://www.my.com/oauth/access_token'</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">public</span> <span class="token variable">$apiBaseUrl</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'https://www.my.com/apis/oauth/v1'</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">protected</span> <span class="token keyword">function</span> <span class="token function-definition function">initUserAttributes</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">api</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'userinfo'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'GET'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>You may also specify default auth scopes.</p>
<blockquote>
<p>Note: Some OAuth providers may not follow OAuth standards clearly, introducing differences, and may require additional efforts to implement clients for.</p>
</blockquote>
<h2 id="oauth-2-0-直接认证" tabindex="-1"><a class="header-anchor" href="#oauth-2-0-直接认证"><span>OAuth 2.0 直接认证</span></a></h2>
<p>OAuth’s protocol of 2.0 version allows several additional work flows, which allows direct authentication without visiting OAuth provider website.</p>
<blockquote>
<p>Note: the authentication work flows, described in this section, usually are not supported by OAuth provider, because they are less secure than regular one. Make sure your provider does support particular work flow before attempt to use it.</p>
</blockquote>
<h3 id="资源所有者密码凭据授予" tabindex="-1"><a class="header-anchor" href="#资源所有者密码凭据授予"><span>资源所有者密码凭据授予</span></a></h3>
<p><a href="https://tools.ietf.org/html/rfc6749#section-4.3" target="_blank" rel="noopener noreferrer">Resource Owner Password Credentials Grant</a> work flow allows direct user authentication by username/password pair without redirect to OAuth provider website.</p>
<p>You may authenticate user via this work flow using [[\yii\authclient\OAuth2::authenticateUser()]]. For example:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$loginForm</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">LoginForm</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$loginForm</span><span class="token operator">-></span><span class="token function">load</span><span class="token punctuation">(</span><span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">request</span><span class="token operator">-></span><span class="token function">post</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token variable">$loginForm</span><span class="token operator">-></span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">/* @var $client \yii\authclient\OAuth2 */</span></span>
<span class="line">    <span class="token variable">$client</span> <span class="token operator">=</span> <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">authClientCollection</span><span class="token operator">-></span><span class="token function">getClient</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'someOAuth2'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">try</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token comment">// direct authentication via username and password:</span></span>
<span class="line">        <span class="token variable">$accessToken</span> <span class="token operator">=</span> <span class="token variable">$client</span><span class="token operator">-></span><span class="token function">authenticateUser</span><span class="token punctuation">(</span><span class="token variable">$loginForm</span><span class="token operator">-></span><span class="token property">username</span><span class="token punctuation">,</span> <span class="token variable">$loginForm</span><span class="token operator">-></span><span class="token property">password</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified"><span class="token punctuation">\</span>Exception</span> <span class="token variable">$e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token comment">// authentication failed, use `$e->getMessage()` for details</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="客户端证书授予" tabindex="-1"><a class="header-anchor" href="#客户端证书授予"><span>客户端证书授予</span></a></h3>
<p><a href="https://tools.ietf.org/html/rfc6749#section-4.4" target="_blank" rel="noopener noreferrer">Client Credentials Grant</a> work flow authenticates only OAuth client (your application) without any third party (actual user) being involved. It is used, if you need to access only some general API, which is not related to the user.</p>
<p>You may authenticate client only via this work flow using [[\yii\authclient\OAuth2::authenticateClient()]]. For example:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token comment">/* @var $client \yii\authclient\OAuth2 */</span></span>
<span class="line"><span class="token variable">$client</span> <span class="token operator">=</span> <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">authClientCollection</span><span class="token operator">-></span><span class="token function">getClient</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'someOAuth2'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// direct authentication of client only:</span></span>
<span class="line"><span class="token variable">$accessToken</span> <span class="token operator">=</span> <span class="token variable">$client</span><span class="token operator">-></span><span class="token function">authenticateClient</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="jwt" tabindex="-1"><a class="header-anchor" href="#jwt"><span>JWT</span></a></h3>
<p>JSON Web Token (JWT) work flow allows authentication of the particular account using <a href="https://tools.ietf.org/html/rfc7515" target="_blank" rel="noopener noreferrer">JSON Web Signature (JWS)</a>. The following example allows authentication of <a href="https://developers.google.com/identity/protocols/OAuth2ServiceAccount" target="_blank" rel="noopener noreferrer">Google Service Account</a>:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>authclient<span class="token punctuation">\</span>clients<span class="token punctuation">\</span>Google</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>authclient<span class="token punctuation">\</span>signature<span class="token punctuation">\</span>RsaSha</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$oauthClient</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Google</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$accessToken</span> <span class="token operator">=</span> <span class="token variable">$oauthClient</span><span class="token operator">-></span><span class="token function">authenticateUserJwt</span><span class="token punctuation">(</span></span>
<span class="line">    <span class="token string single-quoted-string">'your-service-account-id@developer.gserviceaccount.com'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token class-name static-context">RsaSha</span><span class="token operator">::</span><span class="token function">className</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'algorithm'</span> <span class="token operator">=></span> <span class="token constant">OPENSSL_ALGO_SHA256</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'privateCertificate'</span> <span class="token operator">=></span> <span class="token string double-quoted-string">"-----BEGIN PRIVATE KEY-----   ...   -----END PRIVATE KEY-----\n"</span></span>
<span class="line">    <span class="token punctuation">]</span></span>
<span class="line"><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="openid-连接" tabindex="-1"><a class="header-anchor" href="#openid-连接"><span>OpenID 连接</span></a></h2>
<p>This extension provides support for <a href="http://openid.net/connect/" target="_blank" rel="noopener noreferrer">OpenId Connect</a> authentication protocol via [[\yii\authclient\OpenIdConnect]] class.</p>
<p>Application configuration example:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'components'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'authClientCollection'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'yii\authclient\Collection'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'clients'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'google'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'yii\authclient\OpenIdConnect'</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'issuerUrl'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'https://accounts.google.com'</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'clientId'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'google_client_id'</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'clientSecret'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'google_client_secret'</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'google'</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'title'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'Google OpenID Connect'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line"><span class="token punctuation">]</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Authentication workflow is exactly the same as for OAuth2.</p>
<p><strong>Heads up!</strong> ‘OpenID Connect’ protocol uses <a href="http://tools.ietf.org/html/draft-ietf-jose-json-web-signature" target="_blank" rel="noopener noreferrer">JWS</a> verification for the authentication process securing. You will need to install <code v-pre>web-token/jwt-checker</code>, <code v-pre>web-token/jwt-key-mgmt</code>, <code v-pre>web-token/jwt-signature</code>, <code v-pre>web-token/jwt-signature-algorithm-hmac</code>, <code v-pre>web-token/jwt-signature-algorithm-ecdsa</code> and <code v-pre>web-token/jwt-signature-algorithm-rsa</code> libraries in order to use such verification. These libraries are not required by this extension by default. It can be done via composer:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">composer <span class="token keyword">require</span> <span class="token operator">--</span>prefer<span class="token operator">-</span>dist <span class="token string double-quoted-string">"web-token/jwt-checker:>=1.0 &lt;3.0"</span> <span class="token string double-quoted-string">"web-token/jwt-key-mgmt:>=1.0 &lt;3.0"</span> <span class="token string double-quoted-string">"web-token/jwt-signature:>=1.0 &lt;3.0"</span> <span class="token string double-quoted-string">"web-token/jwt-signature-algorithm-hmac:>=1.0 &lt;3.0"</span> <span class="token string double-quoted-string">"web-token/jwt-signature-algorithm-ecdsa:>=1.0 &lt;3.0"</span> <span class="token string double-quoted-string">"web-token/jwt-signature-algorithm-rsa:>=1.0 &lt;3.0"</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>or add</p>
<div class="language-json line-numbers-mode" data-highlighter="prismjs" data-ext="json" data-title="json"><pre v-pre class="language-json"><code><span class="line"><span class="token property">"web-token/jwt-checker"</span><span class="token operator">:</span> <span class="token string">">=1.0 &lt;3.0"</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token property">"web-token/jwt-key-mgmt"</span><span class="token operator">:</span> <span class="token string">">=1.0  &lt;3.0"</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token property">"web-token/jwt-signature"</span><span class="token operator">:</span> <span class="token string">"~1.0 &lt;3.0"</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token property">"web-token/jwt-signature-algorithm-hmac"</span><span class="token operator">:</span> <span class="token string">"~1.0  &lt;3.0"</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token property">"web-token/jwt-signature-algorithm-ecdsa"</span><span class="token operator">:</span> <span class="token string">"~1.0  &lt;3.0"</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token property">"web-token/jwt-signature-algorithm-rsa"</span><span class="token operator">:</span> <span class="token string">"~1.0  &lt;3.0"</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>to the <code v-pre>require</code> section of your composer.json.</p>
<blockquote>
<p>Note: if you are using well-trusted ‘OpenID Connect’ provider, you may disable [[\yii\authclient\OpenIdConnect::$validateJws]], making installation of <code v-pre>web-token</code> library redundant, however it is not recommended as it violates the protocol specification.</p>
</blockquote>
<h2 id="设置-http-客户端" tabindex="-1"><a class="header-anchor" href="#设置-http-客户端"><span>设置 HTTP 客户端</span></a></h2>
<p>This extension uses <a href="https://github.com/yiisoft/yii2-httpclient" target="_blank" rel="noopener noreferrer">yii2-httpclient</a> for HTTP requests. You may need to adjust default HTTP client configuration to be used, for example, in case you need to use special request transport.</p>
<p>Each Auth client has a property <code v-pre>httpClient</code>, which can be used to setup HTTP client used by Auth client. For example:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>authclient<span class="token punctuation">\</span>Google</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$authClient</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Google</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'httpClient'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'transport'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'yii\httpclient\CurlTransport'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>In case you are using [[\yii\authclient\Collection]] component, you can use its property <code v-pre>httpClient</code> to setup HTTP client configuration to all internal Auth clients at once. Application configuration example:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'components'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'authClientCollection'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'yii\authclient\Collection'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token comment">// all Auth clients will use this configuration for HTTP client:</span></span>
<span class="line">            <span class="token string single-quoted-string">'httpClient'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token string single-quoted-string">'transport'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'yii\httpclient\CurlTransport'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'clients'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                <span class="token string single-quoted-string">'google'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                    <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'yii\authclient\clients\Google'</span><span class="token punctuation">,</span></span>
<span class="line">                    <span class="token string single-quoted-string">'clientId'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'google_client_id'</span><span class="token punctuation">,</span></span>
<span class="line">                    <span class="token string single-quoted-string">'clientSecret'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'google_client_secret'</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token string single-quoted-string">'facebook'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">                    <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'yii\authclient\clients\Facebook'</span><span class="token punctuation">,</span></span>
<span class="line">                    <span class="token string single-quoted-string">'clientId'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'facebook_client_id'</span><span class="token punctuation">,</span></span>
<span class="line">                    <span class="token string single-quoted-string">'clientSecret'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'facebook_client_secret'</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">                <span class="token comment">// etc.</span></span>
<span class="line">            <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span></span>
<span class="line">        <span class="token comment">//...</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="第三方认证客户端" tabindex="-1"><a class="header-anchor" href="#第三方认证客户端"><span>第三方认证客户端</span></a></h2>
<p>There are more implementations for various clients:</p>
<ul>
<li><a href="https://github.com/kotchuprik/yii2-instagram-authclient" target="_blank" rel="noopener noreferrer">Instagram</a></li>
<li><a href="https://github.com/yujiandong/yii2-authclient" target="_blank" rel="noopener noreferrer">Weibo, QQ, Wechat</a></li>
<li><a href="https://github.com/yiiauth/gitlab" target="_blank" rel="noopener noreferrer">GitLab</a></li>
<li><a href="https://github.com/yiiauth/spotify" target="_blank" rel="noopener noreferrer">Spotify</a></li>
<li><a href="https://github.com/Worteks/yii2auth-oidc" target="_blank" rel="noopener noreferrer">OIDC</a></li>
</ul>
<blockquote>
<p>💖喜欢本文档的，欢迎点赞、收藏、留言或转发，谢谢支持！<br>
作者邮箱：zhuzixian520@126.com，github地址：<a href="https://github.com/zhuzixian520" target="_blank" rel="noopener noreferrer">github.com/zhuzixian520</a></p>
</blockquote>
</div></template>


